#from calc_manager.plugins_inner.bdf_reader_inner import BDFReader
from calc_manager.plugins_inner.op2_reader_inner import OP2Reader
from calc_manager.plugins_inner.mat_csv_inner import MatCSVReader
from pydantic import BaseModel
from pyNastran.op2.op2 import read_op2

from copy import deepcopy

class CustomBaseModel(BaseModel):
    def __getstate__(self):
        # 获取所有的模型字段
        return self.model_dump()

    def __setstate__(self, state):
        # 使用模型的验证逻辑来设置状态
        object.__setattr__(self, '__dict__', {})
        object.__setattr__(self, '__fields_set__', set())
        self.__init__(**state)


class Parameter(BaseModel):
    sample_num: int 
    sample_float: float

class KeyResult(CustomBaseModel):
    y: float
    rrr: str



def stress_strain(param: Parameter) :
    res =  KeyResult(y=3.14, rrr="rrr")
    return res

#def stress_strain_bak(param: Parameter, bdf_reader: BDFReader, op2_reader: OP2Reader, mat_csv_reader: MatCSVReader) -> Result:
#    # step3: 获取所有单元编号
#    element_ids = bdf_reader.get_element_ids()
#
#    # step4: 识别每个单元的属性类型 pshell/pcomp, 目前示例中仅用了pshell
#    danger_element_results = []
#
#    # for demo cut element_ids only 900 elements
#    element_ids = element_ids[:19]
#    for eid in element_ids:
#        prop_name = bdf_reader.get_element_fields_by_id(eid)["element_prop"]
#        mid = bdf_reader.get_element_fields_by_id(eid)["element_mid"]
#        if prop_name == "PSHELL":
#            # 根据单元编号获取应力值,这里为了有失效单元,数值乘以2倍
#            stress_result = op2_reader.get_shell_element_stress_by_id(eid, bdf_reader) * 2
#            # 再执行自定义算法（本示例仅引用了计算结果中的等效应力和外部材料的屈服应力
#            # 原本业务逻辑是bdf中的材料id和外部材料性能数据csv是一致的,通过此数据进行查找,如附件的10001_FCY.csv;基于单元id查找关联的属性id,再查找相应的材料id
#            # 更新了bdf文件的mat_id=20240005
#            # material_yield_stress = 100
#            material_yield_stress = mat_csv_reader.get_mat_from_csv(mid)
#            if calculate_safety(stress_result, material_yield_stress) < 0:
#                # 打印失效单元
#                print(f"{calculate_safety(stress_result, 100)} {eid}")
#                danger_element_results.append(eid)
#        elif prop_name == "PCOMP":
#            # 复合材料
#            pass
#        else:
#            raise Exception("属性卡片不支持")
#    return Result(y=1)

# 与bdf/nastran无关的数据计算函数,demo简单化
def calculate_safety(model_value: float, material_value: float):
    """计算仿真计算的应力值与材料屈服强度的差值百分比

    Args:
        model_value (float): 仿真计算的应力数值
        material_value (float): 材料的许用应力（如屈服强度、抗拉强度等）

    Returns:
        float: 差值百分比
    """
    result = (material_value - model_value) / material_value
    return result